package com.yanqu.road.server.gameplayer.module.activity.yuanbaolottery;

import com.yanqu.road.dao.impl.player.UserYuanBaoLotteryDaoImpl;
import com.yanqu.road.entity.activity.yuanbaolottery.UserYuanBaoLotteryData;
import com.yanqu.road.entity.activity.yuanbaolottery.YuanBaoLotteryConfig;
import com.yanqu.road.entity.activity.yuanbaolottery.YuanBaoLotteryWeight;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.yuanbaolottery.LogYuanBaoLottery;
import com.yanqu.road.entity.player.UserBagItem;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.YuanBaoLotteryProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.yuanbaolottery.YuanBaoLotteryActivityConfig;
import com.yanqu.road.server.manger.activity.yuanbaolottery.YuanBaoLotteryMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.property.Property;

import java.math.BigDecimal;

public class YuanBaoLotteryModule extends GeneralModule {
    public YuanBaoLotteryModule(GamePlayer player) {
        super(player);
    }

    private UserYuanBaoLotteryData userData;

    @Override
    public boolean loadData() {
        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            userData = new UserYuanBaoLotteryDaoImpl().getUserYuanBaoLotteryData(config.getActivityId(), getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                new UserYuanBaoLotteryDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new UserYuanBaoLotteryDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        initSystemOpen();
    }

    public void resetOneDay() {
        roundReset(true);
    }

    public void initSystemOpen() {
        if (!isSystemOpen()) {
            return;
        }
        initUserData();
        roundReset(false);
        syncConfig();
        syncUserData();
    }

    public void syncUserData() {
        if (userData == null) {
            return;
        }

        YuanBaoLotteryProto.YuanBaoLotteryUserMsg.Builder builder = YuanBaoLotteryProto.YuanBaoLotteryUserMsg.newBuilder();
        builder.setRound(userData.getRound());
        builder.setLotteryCount(userData.getLotteryTimes());
        player.sendPacket(GameProtocol.S_YUANBAO_LOTTERY_USER_SYNC % 20000, builder);
    }

    public void syncConfig() {
        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config == null) {
            return;
        }

        if (!ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        YuanBaoLotteryProto.YuanBaoLotteryConfigMsg.Builder builder = YuanBaoLotteryProto.YuanBaoLotteryConfigMsg.newBuilder();
        for (YuanBaoLotteryConfig lotteryConfig : config.getLotteryConfigList()) {
            YuanBaoLotteryProto.YuanBaoLotteryConfigTemp.Builder lotteryTemp = YuanBaoLotteryProto.YuanBaoLotteryConfigTemp.newBuilder();
            lotteryTemp.setId(lotteryConfig.getId());
            lotteryTemp.setConsume(lotteryConfig.getConsume());
            lotteryTemp.setNeedNum(lotteryConfig.getNeedNum());
            lotteryTemp.setParam(lotteryConfig.getParam());

            builder.addConfigList(lotteryTemp);
        }
        player.sendPacket(GameProtocol.S_YUANBAO_LOTTERY_CONFIG_SYNC % 20000, builder);
    }

    private void initUserData() {
        if (!isSystemOpen()) {
            return;
        }
        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        synchronized (this) {
            if (userData == null || userData.getActivityId() != config.getActivityId()) {
                userData = new UserYuanBaoLotteryData(config.getActivityId(), player.getUserId());
                userData.setRound(config.getNowRound());
            }
        }
    }

    public boolean isSystemOpen() {
        return SystemOpenMgr.systemOpen(player, eSystemId.YuanBaoLottery.getValue());
    }

    public void roundReset(boolean needSync) {
        if (userData == null) {
            return;
        }

        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config == null) {
            return;
        }
        int nowRound = config.getNowRound();
        synchronized (this) {
            if (nowRound !=0 && userData.getRound() != nowRound) {
                userData.setRound(nowRound);
                userData.setLotteryTimes(0);

                recycleLotteryItem();

                if (needSync) {
                    syncUserData();
                }
            }
        }
    }

    public void recycleLotteryItem() {
        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config == null) {
            return;
        }

        int costId = config.getCostId();
        UserBagItem userBagItem = player.getModule(BagModule.class).getUserBagItem(costId);
        if (userBagItem == null) {
            return;
        }

        Property recycleItem = new Property(costId, userBagItem.getNum());
        player.getModule(CurrencyModule.class).removeCurrency(recycleItem, eLogMoneyType.YuanBaoLottery, eLogMoneyType.YuanBaoLotteryRoundRecycle);
    }

    public int lottery(int activityId) {
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        YuanBaoLotteryActivityConfig config = YuanBaoLotteryMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        if (config.getActivityId() != activityId) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        roundReset(true);

        YuanBaoLotteryConfig lotteryConfig = config.getLotteryConfigByTimes(userData.getLotteryTimes() + 1);
        if (lotteryConfig == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        YuanBaoLotteryWeight randomResult = (YuanBaoLotteryWeight) WeightHelper.getRandomResult(lotteryConfig.getWeightList());
        if (randomResult == null) {
            return GameErrorCode.E_ERROR_DATA;
        }

        Property cost = new Property(config.getCostId(), lotteryConfig.getConsume());//道具消耗
        cost.addProperty(GameConfig.GAME_MONEY_INGOTS, lotteryConfig.getNeedNum());//元宝消耗
        if (!player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.YuanBaoLottery, eLogMoneyType.YuanBaoLotteryCost)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        Property reward = new Property(GameConfig.GAME_MONEY_INGOTS, lotteryConfig.getNeedNum());
        BigDecimal multi = new BigDecimal(randomResult.getValue()).divide(BigDecimal.valueOf(1000));
        reward.goodMulti(multi);

        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.YuanBaoLottery, eLogMoneyType.YuanBaoLotteryReward);

        userData.setLotteryTimes(userData.getLotteryTimes() + 1);

        YuanBaoLotteryProto.YuanBaoLotteryGetRespMsg.Builder resp = YuanBaoLotteryProto.YuanBaoLotteryGetRespMsg.newBuilder();
        resp.setRet(0);
        resp.setResultPos(randomResult.getPos());
        resp.setReward(reward.toHelperString());

        player.sendPacket(GameProtocol.S_YUANBAO_LOTTERY_GET % 20000, resp);

        AutoLogMgr.add(new LogYuanBaoLottery(
                userData.getActivityId(),
                getUserId(),
                userData.getRound(),
                userData.getLotteryTimes(),
                lotteryConfig.getNeedNum(),
                randomResult.getValue().intValue(),
                reward.getCountByGoodsId(GameConfig.GAME_MONEY_INGOTS).intValue()
        ));

        syncUserData();
        return 0;
    }

    public int getRound() {
        initUserData();
        if (userData == null) {
            return 0;
        }
        roundReset(true);
        return userData.getRound();
    }
}
